import log from "./logger"
import {EventEmitter} from "../node-test";
import {Qr} from "./interfaces";
import * as crypto from 'crypto';
import {Socket} from "net";

class QrImpl extends EventEmitter implements Qr {
    private bufIn = ''
    private bufOut = ''

    private privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
        "MIIBOwIBAAJBANS/Mu231VLy2QdGm9rznclH5WcbiHnoLzs2uI+O3w5EE3t90KEm\n" +
        "foUKM8cUCOdImeW0UYHnooIj1oA2n48L9gsCAwEAAQJAf02p+/V1AR2wIFpwCKSe\n" +
        "VkNfUkN3dvsoyBYGemDTuISL/kHgfRIai7DTSFJnp80w1fpBNoicg5UfjhaGnPfk\n" +
        "AQIhAPkxbiv9CailMyBAaqxlH0ZrDvQirf8WPAg1EsMvsbrhAiEA2o7n22DU7RN3\n" +
        "nkbOpi53taOET/9iCh4vpR7QlfPIGmsCICnh8/lyuxfcRD6MdSFqkZodTlMcLRBt\n" +
        "pUNf4DpsHrwhAiEAlY5gnj/+tFQz8Hznf9QgWo0QR2WsgtvxIn6ZoWL2NQ0CIQDr\n" +
        "gZVsFAQbfEHkQxy5Y5XnikA8ZyZerifLRHd+K2PLgg==\n" +
        "-----END RSA PRIVATE KEY-----\n";

    private serialIn: Socket;
    private serialOut: Socket;

    public constructor() {
        super();
    }

    public process(buf: string, inout: "in" | "out") {
        const base64Str = buf.replace(';', '');
        const buffer = Buffer.from(base64Str, 'base64');
        try {
            const decryptStr = crypto.privateDecrypt({
                key: this.privateKey,
                padding: crypto.constants.RSA_PKCS1_PADDING // 注意这里的常量值要设置为RSA_PKCS1_PADDING
            }, buffer).toString();
            const strings = decryptStr.split(';');
            const vehicleNumber = strings[0];
            const datetime = parseInt(strings[1]) * 1000;
            if (datetime + 1000 * 60 * 60 > new Date().getTime()) {
                log.info("未过期，车号：", vehicleNumber);
                this.emit("qr", vehicleNumber, inout);
            } else {
                log.info("未过期，车号：", vehicleNumber);
            }
        } catch (e) {
            log.error(e);
        }
    }

    connectIn(): void {
        this.serialIn = new Socket();

        this.serialIn.connect(39998, '127.0.0.1');
        this.serialIn.on("connect", () => {
            log.info("qrInServer on connect");
        })

        this.serialIn.on("data", (buffer: []) => {
            this.bufIn += buffer;
            if (this.bufIn.endsWith(";")) {
                // log.info("qr in buf:", this.bufIn);
                this.process(this.bufIn, "in");
                this.bufIn = '';
            }
        })

        this.serialIn.on("close", () => {
            log.info("qrInServer on close")
            setTimeout(() => {
                log.info("qrInServer reconnect...")
                this.connectIn();
            }, 10000)
        })

        this.serialIn.on('error', function (error) {
            log.info('qrInServer on error: ' + error)
        })
    }

    connectOut(): void {
        this.serialOut = new Socket();

        this.serialOut.connect(39997, '127.0.0.1');
        this.serialOut.on("connect", () => {
            log.info("qrOutServer on connect");
        })

        this.serialOut.on("data", (buffer: []) => {
            this.bufOut += buffer;
            if (this.bufOut.endsWith(";")) {
                // log.info("qr out buf:", this.bufOut);
                this.process(this.bufOut, "out");
                this.bufOut = '';
            }
        })

        this.serialOut.on("close", () => {
            log.info("qrOutServer on close")
            setTimeout(() => {
                log.info("qrOutServer reconnect...")
                this.connectOut();
            }, 10000)
        })

        this.serialOut.on('error', function (error) {
            log.info('qrOutServer on error: ' + error)
        })
    }

    init() {
        this.connectIn();
        this.connectOut();
    }
}

const qr = new QrImpl();
export default qr;